﻿using System.Collections.Generic;
using UBlockly.Scriptable;
using UnityEngine;
using UBlockly.Compotent;

namespace UBlockly.UI
{
    public class VoidVoidTypeNode : Node
    {
        public VoidVoidTypeNode(BlockObject block, NodeScriptable x) : base(block,x) { }
    }
    public class VoidBoolTypeNode : Node
    {
        public VoidBoolTypeNode(BlockObject block, NodeScriptable x) : base(block,x) { }
    }
    public class VoidIntTypeNode : Node
    {
        public VoidIntTypeNode(BlockObject block, NodeScriptable x) : base(block,x) { }
    }
    public sealed class VoidStringTypeNode : Node
    {
        public VoidStringTypeNode(BlockObject block, NodeScriptable x) : base(block,x) { }
    }
    public sealed class BoolVoidTypeNode : Node
    {
        public BoolVoidTypeNode(BlockObject block, NodeScriptable x) : base(block,x) { }
    }
    public sealed class BoolBoolTypeNode : Node
    {
        public BoolBoolTypeNode(BlockObject block, NodeScriptable x) : base(block,x) { }
    }
    public sealed class BoolIntTypeNode : Node
    {
        public BoolIntTypeNode(BlockObject block, NodeScriptable x) : base(block,x) { }
    }
    public sealed class BoolStringTypeNode : Node
    {
        public BoolStringTypeNode(BlockObject block, NodeScriptable x) : base(block,x) { }
    }
    public sealed class IntVoidTypeNode : Node
    {
        public IntVoidTypeNode(BlockObject block, NodeScriptable x) : base(block,x) { }
    }
    public sealed class IntBoolTypeNode : Node
    {
        public IntBoolTypeNode(BlockObject block, NodeScriptable x) : base(block,x) { }
    }
    public sealed class IntIntTypeNode : Node
    {
        public IntIntTypeNode(BlockObject block, NodeScriptable x) : base(block,x) { }
    }
    public sealed class IntStringTypeNode : Node
    {
        public IntStringTypeNode(BlockObject block, NodeScriptable x) : base(block,x) { }
    }
    public sealed class StringVoidTypeNode : Node
    {
        public StringVoidTypeNode(BlockObject block, NodeScriptable x) : base(block,x) { }
    }
    public sealed class StringBoolTypeNode : Node
    {
        public StringBoolTypeNode(BlockObject block, NodeScriptable x) : base(block,x) { }
    }
    public sealed class StringIntTypeNode : Node
    {
        public StringIntTypeNode(BlockObject block, NodeScriptable x) : base(block,x) { }
    }
    public sealed class StringStringTypeNode : Node
    {
        public StringStringTypeNode(BlockObject block, NodeScriptable x) : base(block,x) { }
    }

    public sealed class IfConditionTypeNode : BranchNode
    {
        public IfConditionTypeNode(BlockObject block, NodeScriptable x) : base(block,x) { }

        public override bool IsNullBranch => throw new System.NotImplementedException();

        public override int BranchCount => 1;

        public override LinkedList<Node> GetBranch(int id)
        {
            throw new System.NotImplementedException();
        }

        public override Node GetBranchRoot(int id)
        {
            throw new System.NotImplementedException();
        }
    }
    public sealed class IfElseConditionTypeNode : BranchNode
    {
        ULinkedList<Node> IfBranch;
        ULinkedList<Node> ElseBranch;
        public IfElseConditionTypeNode(BlockObject block, NodeScriptable x) : base(block, x)
        {
            IfBranch = new ULinkedList<Node>();
            ElseBranch = new ULinkedList<Node>();
        }

        public override void Init()
        {
            base.Init();
            var ifBlock = Block.Find("Condition-0");
            var elseBlock = Block.Find("Condition-1");

            CreateBranchRoot(0, new EmptyScriptNode(ifBlock.GetComponent<BlockObject>()));
            CreateBranchRoot(1, new EmptyScriptNode(elseBlock.GetComponent<BlockObject>()));
        }

        public override bool IsNullBranch => IfBranch.Count > 1 && ElseBranch.Count > 1;

        public override int BranchCount => 2;

        public override LinkedList<Node> GetBranch(int id)
        {
            if (id == 0)
                return IfBranch;
            else if (id == 1)
                return ElseBranch;
            return null;
        }

        public override Node GetBranchRoot(int id)
        {
            if (id == 0)
                return IfBranch.First.Value;
            else if (id == 1)
                return ElseBranch.First.Value;
            return null;
        }
    }
    public sealed class RepeatConditionTypeNode : BranchNode
    {
        public RepeatConditionTypeNode(BlockObject block, NodeScriptable x) : base(block, x) { }

        public override bool IsNullBranch => throw new System.NotImplementedException();

        public override int BranchCount => 1;

        public override LinkedList<Node> GetBranch(int id)
        {
            throw new System.NotImplementedException();
        }

        public override Node GetBranchRoot(int id)
        {
            throw new System.NotImplementedException();
        }
    }
    public sealed class WhileConditionTypeNode : BranchNode
    {
        public WhileConditionTypeNode(BlockObject block, NodeScriptable x) : base(block, x) { }

        public override bool IsNullBranch => throw new System.NotImplementedException();

        public override int BranchCount => 1;

        public override LinkedList<Node> GetBranch(int id)
        {
            throw new System.NotImplementedException();
        }

        public override Node GetBranchRoot(int id)
        {
            throw new System.NotImplementedException();
        }
    }
    public sealed class DoWhileConditionTypeNode : BranchNode
    {
        public DoWhileConditionTypeNode(BlockObject block, NodeScriptable x) : base(block, x) { }

        public override bool IsNullBranch => throw new System.NotImplementedException();

        public override int BranchCount => 1;

        public override LinkedList<Node> GetBranch(int id)
        {
            throw new System.NotImplementedException();
        }

        public override Node GetBranchRoot(int id)
        {
            throw new System.NotImplementedException();
        }
    }
}
